home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / apps / sprdshts / viscalc.lzh / VISCALC / LEX.C < prev    next >
C/C++ Source or Header  |  1985-11-20  |  9KB  |  348 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Lexical analyser
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        Major mods to run on VMS and AMIGA, 1/17/87
  10.  *
  11.  */
  12.  
  13.  
  14.  
  15. #include "sc.h"
  16. #include <ctype.h>
  17. #ifdef VMS
  18. #include "y_tab.h"
  19. #else
  20. #ifdef TOS
  21. #include "y_tab.h"
  22. #else
  23. #include "y.tab.h"
  24. #endif
  25. #endif
  26.  
  27. extern char *malloc();
  28. char *strtof();
  29.  
  30. struct key {
  31.     char *key;
  32.     int val;
  33. };
  34.  
  35. struct key experres[] = {
  36. #include "experres.h"
  37.     0, 0};
  38.  
  39. struct key statres[] = {
  40. #include "statres.h"
  41.     0, 0};
  42.  
  43. #define ctl(x) ('x'&037)
  44.  
  45. yylex () {
  46.     register char *p = line+linelim;
  47.     int ret = -1;
  48.     while (isspace(*p)) p++;
  49.     if (*p==0) ret = -1;
  50.     else if (isalpha(*p)) {
  51.     char *tokenst = p;
  52.     register tokenl;
  53.     register struct key *tbl;
  54.     while (isalpha(*p)) p++;
  55.     if (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
  56.         register  col;
  57.         ret = COL;
  58.         col = ((tokenst[0] & 0137) - 'A');
  59.         if (p == tokenst+2)
  60.         col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
  61.         yylval.ival =  col;
  62.     } else {
  63.         ret = WORD;
  64.         tokenl = p-tokenst;
  65.         for (tbl = linelim ? experres : statres; tbl->key; tbl++)
  66.             if (((tbl->key[0]^tokenst[0])&0137)==0
  67.              && tbl->key[tokenl]==0) {
  68.             register i = 1;
  69.             while (i<tokenl && ((tokenst[i]^tbl->key[i])&0137)==0)
  70.                 i++;
  71.             if (i>=tokenl) {
  72.                 ret = tbl->val;
  73.                 break;
  74.             }
  75.             }
  76.         if (ret==WORD) { 
  77.         linelim = p-line;
  78.         yyerror ("Unintelligible word");
  79.         }
  80.     }
  81.     } else if ((*p == '.') || isdigit(*p)) {
  82.     register long v = 0;
  83.     char *nstart = p;
  84.     if (*p != '.') {
  85.         do v = v*10 + (*p-'0');
  86.         while (isdigit(*++p));
  87.     }
  88.     if (*p=='.' || *p == 'e' || *p == 'E') {
  89.         ret = FNUMBER;
  90.         p = strtof(nstart, &yylval.fval);
  91.     } else {
  92.             if((int)v != v)
  93.             {
  94.                 ret = FNUMBER;
  95.                 yylval.fval = v;
  96.             }
  97.             else
  98.             {
  99.  
  100.                 ret = NUMBER;
  101.                 yylval.ival = v;
  102.             }
  103.     }
  104.     } else if (*p=='"') {
  105.     /* This storage is never freed.  Oh well.  -MDW */
  106.     char *ptr;
  107.         ptr = p+1;
  108.         while(*ptr && *ptr++ != '"');
  109.         ptr = (char *)malloc((unsigned)(ptr-p));
  110.     yylval.sval = ptr;
  111.     p += 1;
  112.     while (*p && *p!='"') *ptr++ = *p++;
  113.     *ptr = 0;
  114.     if (*p) p += 1;
  115.     ret = STRING;
  116.     } else if (*p=='[') {
  117.     while (*p && *p!=']') p++;
  118.     if (*p) p++;
  119.     linelim = p-line;
  120.     return yylex();
  121.     } else ret = *p++;
  122.     linelim = p-line;
  123.     return ret;
  124. }
  125.  
  126. #define N_KEY 26
  127.  
  128. struct key_map {
  129.     char *k_str;
  130.     char k_val;
  131.     char k_index;
  132. }; 
  133.  
  134. struct key_map km[N_KEY];
  135.  
  136. initkbd()
  137. {
  138.     int i;
  139.  
  140.     /* cursor set mode */
  141.     km[0].k_str  = "\033OD"; km[0].k_val  = ctl(b);
  142.     km[1].k_str  = "\033OC"; km[1].k_val  = ctl(f);
  143.     km[2].k_str  = "\033OA"; km[2].k_val  = ctl(p);
  144.     km[3].k_str  = "\033OB"; km[3].k_val  = ctl(n);
  145.     /* cursor reset mode */
  146.     km[4].k_str  = "\033[D"; km[4].k_val  = ctl(b);
  147.     km[5].k_str  = "\033[C"; km[5].k_val  = ctl(f);
  148.     km[6].k_str  = "\033[A"; km[6].k_val  = ctl(p);
  149.     km[7].k_str  = "\033[B"; km[7].k_val  = ctl(n);
  150.     /* CSI arrows */
  151.     km[8].k_str  = "\233D";  km[8].k_val  = ctl(b);
  152.     km[9].k_str  = "\233C";  km[9].k_val  = ctl(f);
  153.     km[10].k_str = "\233A";  km[10].k_val = ctl(p);
  154.     km[11].k_str = "\233B";  km[11].k_val = ctl(n);
  155.     /* application keypad mode */
  156.     km[12].k_str = "\033Op"; km[12].k_val = '0';
  157.     km[13].k_str = "\033Oq"; km[13].k_val = '1';
  158.     km[14].k_str = "\033Or"; km[14].k_val = '2';
  159.     km[15].k_str = "\033Os"; km[15].k_val = '3';
  160.     km[16].k_str = "\033Ot"; km[16].k_val = '4';
  161.     km[17].k_str = "\033Ou"; km[17].k_val = '5';
  162.     km[18].k_str = "\033Ov"; km[18].k_val = '6';
  163.     km[19].k_str = "\033Ow"; km[19].k_val = '7';
  164.     km[20].k_str = "\033Ox"; km[20].k_val = '8';
  165.     km[21].k_str = "\033Oy"; km[21].k_val = '9';
  166.     km[22].k_str = "\033Om"; km[22].k_val = '-';
  167.     km[23].k_str = "\033Ol"; km[23].k_val = ',';
  168.     km[24].k_str = "\033On"; km[24].k_val = '.';
  169.     km[25].k_str = "\033OM"; km[25].k_val = ctl(m);
  170. }
  171.  
  172. nmgetch() 
  173. {
  174.     register int c;
  175.     register struct key_map *kp;
  176.     register struct key_map *biggest;
  177.     register int i;
  178.     int almost;
  179.     int maybe;
  180.  
  181.     static char dumpbuf[10];
  182.     static char *dumpindex;
  183.  
  184.     void timeout();
  185.  
  186.     if (dumpindex && *dumpindex)
  187.         return (*dumpindex++);
  188.  
  189.     c = ttgetc();
  190.     biggest = 0;
  191.     almost = 0;
  192.  
  193.     for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
  194.     if (!kp->k_str)
  195.         continue;
  196.     if (c == (kp->k_str[kp->k_index] & 0xFF)) {
  197.         almost = 1;
  198.         kp->k_index++;
  199.         if (kp->k_str[kp->k_index] == 0) {
  200.         c = kp->k_val;
  201.                    for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  202.                 kp->k_index = 0;
  203.             return(c);
  204.         }
  205.     }
  206.     if (!biggest && kp->k_index)
  207.         biggest = kp;
  208.         else if (kp->k_index && biggest->k_index < kp->k_index)
  209.         biggest = kp;
  210.     }
  211.  
  212.     if (almost) return(nmgetch());
  213.  
  214.     if (biggest) {
  215.     for (i = 0; i<biggest->k_index; i++) 
  216.         dumpbuf[i] = biggest->k_str[i];
  217.     dumpbuf[i++] = c;
  218.     dumpbuf[i] = 0;
  219.     dumpindex = &dumpbuf[1];
  220.            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  221.         kp->k_index = 0;
  222.     return (dumpbuf[0]);
  223.     }
  224.  
  225.     return(c);
  226. }
  227.  
  228.  
  229. int dbline;
  230.  
  231. debug (fmt, a, b, c) {
  232.     move(2+(dbline++%22),80-60);
  233.     printw(fmt,a,b,c);
  234.     clrtoeol();
  235. }
  236.  
  237. /*
  238.  * This converts a floating point number of the form
  239.  * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  240.  * to floating point. 
  241.  * p is advanced.
  242.  */
  243.  
  244. char *
  245. strtof(p, res)
  246. register char *p;
  247. double *res;
  248. {
  249.     double acc;
  250.     int sign;
  251.     double fpos;
  252.     int exp;
  253.     int exps;
  254.  
  255.     acc = 0.0;
  256.     sign = 1;
  257.     exp = 0;
  258.     exps = 1;
  259.     if (*p == '+')
  260.         p++;
  261.     else if (*p == '-') {
  262.         p++;
  263.         sign = -1;
  264.     }
  265.     while (isdigit(*p)) {
  266.         acc = acc * 10.0 + (double)(*p - '0');
  267.         p++;
  268.     }
  269.     if (*p == 'e' || *p == 'E') {
  270.         p++;
  271.         if (*p == '+')
  272.         p++;
  273.         else if (*p == '-') {
  274.         p++;
  275.         exps = -1;
  276.         }
  277.         while(isdigit(*p)) {
  278.         exp = exp * 10 + (*p - '0');
  279.         p++;
  280.         }
  281.     }
  282.     if (*p == '.') {
  283.     fpos = 1.0/10.0;
  284.     p++;
  285.     while(isdigit(*p)) {
  286.         acc += (*p - '0') * fpos;
  287.         fpos *= 1.0/10.0;
  288.         p++;
  289.     }
  290.     }
  291.     if (*p == 'e' || *p == 'E') {
  292.     exp = 0;
  293.     exps = 1;
  294.         p++;
  295.     if (*p == '+')
  296.         p++;
  297.     else if (*p == '-') {
  298.         p++;
  299.         exps = -1;
  300.     }
  301.     while(isdigit(*p)) {
  302.         exp = exp * 10 + (*p - '0');
  303.         p++;
  304.     }
  305.     }
  306.     if (exp) {
  307.     if (exps > 0)
  308.         while (exp--)
  309.         acc *= 10.0;
  310.     else
  311.         while (exp--)
  312.         acc *= 1.0/10.0;
  313.     }
  314.     if (sign > 0)
  315.         *res = acc;
  316.     else
  317.     *res = -acc;
  318.  
  319.     return(p);
  320. }
  321.  
  322. help () {
  323.     move(2,0);
  324.     clrtobot();
  325.     dbline = 0;
  326.     debug ("                 Cursor cmds:");
  327.     debug ("  ^n j next row       ^p k prev. row      ^g erase cmd");
  328.     debug ("  ^f l fwd col        ^b h back col       ^r redraw screen");
  329.     debug ("   0 $ first, end col");
  330.     debug ("                 Cell cmds:");
  331.     debug (" \" < > enter label       = enter value     x clear cell");
  332.     debug ("     c copy cell         m mark cell      ^t line 1 on/off");  
  333.     debug ("    ^a type value       ^e type expr.     ^v type vbl name");
  334.     debug ("                 Row, Column cmds:");
  335.     debug (" ar ac dup           ir ic insert      sr sc show");
  336.     debug (" dr dc delete        zr zc hide        pr pc pull");
  337.     debug (" vr vc value only        f format");
  338.     debug ("                 File cmds:");
  339.     debug ("